# 继承和多态
class Animal(object):
    def run(self):
        print('Animal is running...')
    def eat(self):
        print('Animal is eating...')

class Dog(Animal):
    def run(self):
        print('Dog is running...')
    def eat(self):
        print('Animal is eating meat')

class Cat(Animal):
    def run(self):
        print('Cat is running...')
    def eat(self):
        print('Animal is eating fish')

def run_twice(animal):
    animal.run()
    animal.run()

class Tortoise(Animal):
    def run(self):
        print('Tortoise is running slowly...')

# 继承和多态的好处就是，当对 Animal 子类进行扩展时，任何依赖 Animal 作为参数的函数或者方法都可以不加修改的正常运行
# 符合开闭原则：对扩展开放，对修改封闭
run_twice(Tortoise())

# 静态语言（例如 Java），如果需要传入Animal类型，则传入的对象必须是Animal类型或者它的子类，否则，将无法调用run()方法。
# 而像 python 这种动态语言，则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了：
class Timer(object):
    def run(self):
        print('Start...')
run_twice(Timer())
# 这就是动态语言的“鸭子类型”，它并不要求严格的继承体系，一个对象只要“看起来像鸭子，走起路来像鸭子”，那它就可以被看做是鸭子。
# Python的“file-like object“就是一种鸭子类型。对真正的文件对象，它有一个read()方法，返回其内容。但是，许多对象，只要有read()方法，都被视为“file-like object“。许多函数接收的参数就是“file-like object“，你不一定要传入真正的文件对象，完全可以传入任何实现了read()方法的对象。

